<script lang="ts" setup name="MedicalExaminerDesk">
import {PageConfig, defaultPage, defaultPageSize, defaultPageSizes, defaultLayout} from '@/components/dTable/dFooter'
import {SearchFromItem} from '@/components/dTable/dHeader'
import {HeaderData, RowOperbuttons, Operation as Oper} from '@/components/dTable/dTable'
import operation from '@/components/dTable/components/operation.vue'
import pageContainer from '@/components/pageContainer.vue'
import dTablePromote from '@/components/dTable/dTablePromote.vue'
import dIcon from '@/components/dIcon.vue'
import addArchives from '@/views/pages/publicHealthExamination/residentArchives/addArchives.vue'
import {ElMessage, FormRules} from 'element-plus/es'
import {computed, onActivated, onBeforeMount, onUnmounted, reactive, ref} from 'vue'
import {getYearMonthDayStr, IdCard, NoNumber, PositiveInteger, transfDicArrData} from '@/util/common'
import {routerPush} from '@/util/router'
import {getDiagnosticTable, DiagnosticTableParams, getDoctorList, rejectCheckupRegister} from '@/api/medicalExaminerDesk/medicalExaminerDesk'
import {SeleteData, ColorTheme} from '@/api/config'
import {getTeamListAll, SelectTeamLsit} from '@/api/publicHealthExamination/communitySettings'
import useCommon from '@/store/common'
import useUser from '@/store/user'
import {showMessageBox} from '@/util/element'
import {getAllCategoryList} from '@/api/physicalExaminationManager/majorCategories'
import {getPersonalByIdNo} from '@/api/publicHealthExamination/physicalExaminationRegister'
import {ResidentList} from '@/api/publicHealthExamination/residentArchives'
import {HXGCReader} from '@/util/idReader'
const common = useCommon.setup().store

// 岗位名称
const jobName = computed(() => {
  return useUser.setup().store.$state?.userInfor?.jobName || ''
})
//显示加载状态
const showLoading = ref(false)

//当前页面 表格数据 定义
const tableData = ref<Array<RowOperbuttons>>([])

// 身份证读取实例
const IDReader = ref()

// 社区下拉
const selectTeamLsit = ref<Array<SelectTeamLsit>>([])
// 既往史下拉
const pastHistoryLsit = ref<Array<SeleteData>>([])
// 民族下拉
const seleteNationData = ref<Array<SeleteData>>([])
// 体检状态下拉
const selectRegisterStatus = ref<Array<SeleteData>>([])
// 医生下拉
const selectDoctorList = ref<Array<SeleteData>>([])
// 体检大类下拉
const selectCheckupCategory = ref<Array<SeleteData>>([])

//表格头部数据定义
const tableHeaderData = ref<Array<HeaderData>>([
  {prop: 'checkupNo', label: '体检号', columnType: 'text', 'min-width': '100'},
  {prop: 'personName', label: '姓名', columnType: 'slot', 'min-width': '100'},
  {prop: 'idNo', label: '身份证', columnType: 'text', 'min-width': '100'},
  {prop: 'gender', label: '性别', columnType: 'text', 'width': '70'},
  {prop: 'age', label: '年龄', columnType: 'text', 'width': '70'},
  {prop: 'phone', label: '联系电话', columnType: 'text', 'min-width': '100'},
  {prop: 'teamName', label: '社区', columnType: 'text', 'min-width': '100'},
  {prop: 'address', label: '居住地址', columnType: 'text', 'min-width': '100'},
  {prop: 'phyDate', label: '体检日期', columnType: 'text', 'min-width': '100'},
  {prop: 'notTestCategory', label: '未检大类', columnType: 'text', 'min-width': '100'},
  {prop: 'registerStatusName', label: '体检状态', columnType: 'text', 'width': '90'},
  {prop: 'oper', label: '操作', columnType: 'slot', align: 'center', width: '264', fixed: 'right'}
])

//搜索项数据定义
const searchFromItems = ref<Array<SearchFromItem>>([
  {label: '身份证号', placeholder: '请输入身份证号', prop: 'idNo', type: 'slot', slotName: 'idNo'},
  {label: '体检日期', placeholder: ['开始时间', '结束时间'], type: 'antdRange', prop: 'phyDate', showTime: false, dateFormat: 'YYYY-MM-DD', style: {width: '320px'}},
  {label: '体检号', placeholder: '请输入体检号', prop: 'checkupNo', type: 'input', enterSubmit: true},
  {label: '姓名', placeholder: '请输入姓名', prop: 'personName', type: 'input', enterSubmit: true},
  {label: '年龄段', placeholder: '请输入年龄段', prop: 'ageStage', type: 'slot', slotName: 'ageStage'},
  {label: '体检医生', placeholder: '请选择体检医生', prop: 'registerDoctorId', type: 'selete', seleteData: selectDoctorList.value, filterable: true},
  {label: '社区', placeholder: '请选择社区', prop: 'teamId', type: 'selete', seleteData: selectTeamLsit.value, filterable: true},
  {label: '体检状态', placeholder: '请选择体检状态', prop: 'registerStatus', type: 'selete', seleteData: selectRegisterStatus.value, filterable: true},
  {label: '未检大类', placeholder: '请选择未检大类', prop: 'notTestCategoryIdsArr', type: 'selete', multiple: true, seleteData: selectCheckupCategory.value, filterable: true}
])

// 表格筛选参数
const searchFromData = reactive<DiagnosticTableParams>({
  phyDate: [getYearMonthDayStr(Date.now()), getYearMonthDayStr(Date.now())]
})

// 编辑人员弹窗
const showArchivesDialog = ref<boolean>(false)

//编辑档案管理
const archivesData = reactive<Partial<ResidentList>>({})

//判断年龄
const ageStage = (_rule, _value: string, callback) => {
  if (!searchFromData.minAge && !searchFromData.maxAge) {
    callback()
    return
  }
  const vLeft = searchFromData.minAge
  const vRight = searchFromData.maxAge
  if (vLeft && !PositiveInteger.test(searchFromData.minAge || '')) {
    callback(new Error('请输入正整数'))
  } else if (vRight && !PositiveInteger.test(searchFromData.maxAge || '')) {
    callback(new Error('请输入正整数'))
  } else {
    callback()
  }
}

// 判断年龄前后大小
const ageStageBigger = (_rule, _value: string, callback) => {
  const vLeft = searchFromData.minAge
  const vRight = searchFromData.maxAge
  if (vLeft && vRight && Number(vLeft) > Number(vRight)) {
    return callback(new Error('起始值应小于结束值'))
  } else {
    return callback()
  }
}

const searchFromRules = reactive<FormRules>({
  idNo: [
    {message: '长度应不超过18个字符', max: 18, trigger: ['change', 'blur']},
    {message: '请输入正确的身份证号码', pattern: IdCard, trigger: ['blur']}
  ],
  ageStage: [
    {message: '请输入正整数', validator: ageStage, trigger: ['change', 'blur']},
    {validator: ageStageBigger, trigger: ['change', 'blur']}
  ],
  personName: [
    {
      message: '长度应不超过20个字符',
      max: 20,
      trigger: ['change', 'blur']
    },
    {
      message: '请输入汉字、字母、字符',
      pattern: NoNumber,
      trigger: ['change', 'blur']
    }
  ]
})

//分页配置
const pageConfig = reactive<PageConfig>({
  currentPage: defaultPage,
  pageSize: defaultPageSize,
  pageSizes: defaultPageSizes,
  total: 0,
  disabled: false,
  layout: defaultLayout
})

// 操作按钮定义组合
const rowOperButtons1: Array<Oper> = [
  {code: 'startInspection', label: '开始体检'},
  {code: 'chineseMedicine', label: '中医体质辨识'},
  {code: 'rejectInspection', label: '拒检', elType: 'danger', plain: true}
]
const rowOperButtons2: Array<Oper> = [
  {code: 'startInspection', label: '开始体检'},
  {code: 'chineseMedicine', label: '中医体质辨识'}
]
const rowOperButtons3: Array<Oper> = [
  {code: 'lookInspection', label: '查看体检', elType: 'default'},
  {code: 'lookChineseMedicine', label: '查看中医体质辨识', elType: 'default'}
]

/**
 * @description: 查询表格数据
 * @param {*} resetPage 重置页码
 * @return {*}
 */
const searchData = (resetPage?: boolean) => {
  showLoading.value = true
  if (resetPage) pageConfig.currentPage = 1
  //输入一个年龄补全另一个年龄
  if (searchFromData.minAge && !searchFromData.maxAge) {
    searchFromData.maxAge = searchFromData.minAge
  }
  if (!searchFromData.minAge && searchFromData.maxAge) {
    searchFromData.minAge = searchFromData.maxAge
  }
  // 请求参数
  const params: DiagnosticTableParams = {
    ...searchFromData
  }
  params.page = pageConfig.currentPage
  params.limit = pageConfig.pageSize
  // 未检大类筛选
  searchFromData.notTestCategoryIdsArr?.length ? (params.notTestCategories = searchFromData.notTestCategoryIdsArr.join(',')) : delete params.notTestCategories
  delete params.notTestCategoryIdsArr
  searchFromData.phyDate?.length ? (params.startDate = searchFromData.phyDate[0] + ' 00:00:00') : delete params.startDate
  searchFromData.phyDate?.length ? (params.endDate = searchFromData.phyDate[1] + ' 23:59:59') : delete params.endDate
  delete params.phyDate
  getDiagnosticTable(params)
    .then((res) => {
      const {data} = res.data
      tableData.value = data.records.map((item) => {
        // 当前账号的岗位为非医生时，仅支持查看操作，不可编辑开始体检、中医体质辨识的数据
        if (jobName.value === '医生') {
          // registerStatus 1 已登记  2 未总检  其余的是已总检、已打印、已发放、拒检
          item.oper = item.registerStatus === 1 ? rowOperButtons1 : item.registerStatus === 2 ? rowOperButtons2 : rowOperButtons3
        } else {
          item.oper = rowOperButtons3
        }
        return item
      })
      pageConfig.total = data.total === null ? 0 : data.total
    })
    .catch((err) => {
      console.warn(err)
    })
    .finally(() => {
      showLoading.value = false
    })
}

//搜索事件
const onSubmit = () => {
  searchData(true)
}

//清除搜索栏数据事件
const clearForm = () => {
  delete searchFromData.minAge
  delete searchFromData.maxAge
  searchFromData.phyDate = [getYearMonthDayStr(Date.now()), getYearMonthDayStr(Date.now())]
  searchData(true)
}

//清空搜索表单事件
const onFormClear = () => {
  clearForm()
}

//分页尺寸改变事件
const onSizeChange = () => {
  searchData(true)
}

//当前页改变事件
const onCurrentChange = () => {
  searchData()
}

/**
 * @description: 身份证读卡器
 * @return {*}
 */
const onReadIdCard = () => {
  IDReader.value &&
    IDReader.value
      .readIdCard()
      .then((res) => {
        searchFromData.idNo = res.idNum // 身份证号
      })
      .catch((err) => {
        console.warn(err)
      })
}

/**
 * @description: 打开档案管理人员编辑
 * @param {*} idNo
 * @return {*}
 */
const openArchivesDialog = (idNo: string) => {
  getPersonalByIdNo({idNo})
    .then((res) => {
      const {data} = res.data
      // 能否在社区下拉中找到该社区
      const index = selectTeamLsit.value.findIndex((item) => {
        return item.value === data.teamId
      })
      archivesData.id = data.id
      archivesData.name = data.name
      archivesData.age = data.age
      archivesData.gender = data.gender
      archivesData.idNo = data.idNo
      archivesData.nation = data.nation
      archivesData.phone = data.phone
      archivesData.portrait = data.portrait
      archivesData.pastHistory = data.pastHistory
      // 社区被删除了就置空社区id
      archivesData.teamId = index !== -1 ? data.teamId : ''
      archivesData.address = data.address
      showArchivesDialog.value = true
    })
    .catch((err) => {
      console.warn(err)
    })
}

/**
 * @description: 关闭人员修改弹窗
 * @return {*}
 */
const onArchivesDialogClose = () => {
  showArchivesDialog.value = false
  onSubmit()
}

// 行操作插槽事件
const cellOperation = (code: string, row) => {
  switch (code) {
  // 开始体检
  case 'startInspection':
    routerPush('BeginPhysicalExamination', {checkupRegisterId: row.id})
    break
    // 中医体质辨识
  case 'chineseMedicine':
    routerPush('ConstitutionIdentify', row)
    break
    // 拒检
  case 'rejectInspection':
    showMessageBox('是否确认拒检？', {title: '拒检确认', mesageType: 'base'})
      .then(() => {
        rejectCheckupRegister(row.id).then(() => {
          ElMessage.success('拒检成功！')
          searchData()
        })
      })
      .catch((error) => {
        console.warn(error)
      })
    break
    // 查看体检
  case 'lookInspection':
    routerPush('BeginPhysicalExamination', {checkupRegisterId: row.id, disEdit: true})
    break
    // 查看体质辨识
  case 'lookChineseMedicine':
    routerPush('ConstitutionIdentify', row)
    break
  }
}

/**
 * @description: 获取字典值
 * @return {*}
 */
const getDict = () => {
  selectRegisterStatus.value.length = 0
  common
    .getDicData('physical_examination')
    .then((res) => {
      const arr: Array<SeleteData> = transfDicArrData(res)
      arr.forEach((item) => {
        selectRegisterStatus.value.push(item)
      })
    })
    .finally(() => {
      searchData() // 列表数据
    })
  // 民族下拉
  seleteNationData.value.length = 0
  common.getDicData('nation').then((res) => {
    const arr: Array<SeleteData> = transfDicArrData(res)
    arr.forEach((item) => {
      seleteNationData.value.push(item)
    })
  })
  // 既往史下拉
  pastHistoryLsit.value.length = 0
  common.getDicData('past_history').then((res) => {
    res &&
      res?.forEach((item) => {
        pastHistoryLsit.value.push({label: item.dictItemName, value: item.dictItemName})
      })
  })
}

/**
 * @description: 获取社区下拉
 * @return {*}
 */
const getTeamSelect = () => {
  selectTeamLsit.value.length = 0
  getTeamListAll().then((res) => {
    res.data.data?.length &&
      res.data.data.forEach((item) => {
        selectTeamLsit.value.push({label: item.name, value: item.id || '', address: `${item.regionName || ''}${item.address || ''}`})
      })
  })
}

/**
 * @description: 获取体检医生列表
 * @return {*}
 */
const getDoctorSelect = () => {
  selectDoctorList.value.length = 0
  getDoctorList().then((res) => {
    const {data} = res.data
    data.length &&
      data.forEach((item) => {
        selectDoctorList.value.push({label: item.userName, value: item.id || ''})
      })
  })
}

/**
 * @description: 获取体检大类下拉
 * @return {*}
 */
const getCheckupCategoryList = () => {
  selectCheckupCategory.value.length = 0
  getAllCategoryList().then((res) => {
    const {data} = res.data
    data.length &&
      data.forEach((item) => {
        selectCheckupCategory.value.push({label: item.categoryName, value: item.categoryName || ''})
      })
  })
}

onBeforeMount(() => {
  IDReader.value = new HXGCReader()
  useCommon.setup().store.getFields() // 获取开始体检-体检项目的必填字段
})

onActivated(() => {
  getDict() // 字典
  getTeamSelect() // 社区下拉
  getDoctorSelect() // 体检医生列表
  getCheckupCategoryList() // 体检大类下拉
})

onUnmounted(() => {
  IDReader.value = null
})
</script>
<template>
  <page-container>
    <d-table-promote
      :stripe="true"
      :show-loading="showLoading"
      :table-data="tableData"
      :table-header-data="tableHeaderData"
      :page-config="pageConfig"
      :search-form-data="searchFromData"
      :search-rules="searchFromRules"
      :search-form-items="searchFromItems"
      search-from-justify="flexStart"
      @form-submit="onSubmit"
      @form-clear="onFormClear"
      @size-change="onSizeChange"
      @current-change="onCurrentChange"
    >
      <template #oper="scope">
        <operation :row="scope.row" :col="scope.item" @opertion-click="cellOperation" />
      </template>
      <template #personName="scope">
        <el-tooltip effect="dark" :content="scope.row.personName" placement="top">
          <a class="table-left-row-name" @click="openArchivesDialog(scope.row.idNo)">
            {{ scope.row.personName }}
          </a>
        </el-tooltip>
      </template>
      <template #idNo>
        <el-input v-model="searchFromData.idNo" placeholder="请输入身份证号码">
          <template #suffix>
            <d-icon
              :icon-config="{
                icon: 'common-id-card',
                type: 'custom',
                size: 18,
                color: ColorTheme
              }"
              @click="onReadIdCard"
            />
          </template>
        </el-input>
      </template>
      <template #ageStage>
        <div>
          <el-row :gutter="5">
            <el-col :span="11">
              <el-input v-model="searchFromData.minAge" clearable placeholder="最小年龄" label="" @keyup.enter="onSubmit" />
            </el-col>
            <el-col :span="2">
              ~
            </el-col>
            <el-col :span="11">
              <el-input v-model="searchFromData.maxAge" clearable placeholder="最大年龄" label="" @keyup.enter="onSubmit" />
            </el-col>
          </el-row>
        </div>
      </template>
    </d-table-promote>
    <add-archives
      v-if="showArchivesDialog"
      :show-dialog="showArchivesDialog"
      dialog-type="edit"
      :archives-data="archivesData"
      :selete-nation-data="seleteNationData"
      :select-team-lsit="selectTeamLsit"
      :past-history-lsit="pastHistoryLsit"
      :id-reader="IDReader"
      :other-page-dialog="true"
      @close="onArchivesDialogClose()"
    />
  </page-container>
</template>
<style lang="less" scoped>
.table-left-row-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-decoration: underline;
  color: var(--theme-color);
}
</style>
